/*
 * Hus_Button.c
 *
 *  Created on: 2020年3月3日
 *      Author: HpDadi
 */
#include "Hus_Button.h"
#include "stdio.h"


//Hus_ButtonDataStruct husButtonDatastruct = {
//		GPIOA, //!!!!!!Need to be changed
//		GPIO_PIN_6, //!!!!!Need to be changed
//		GPIO_PIN_RESET, //!!!!!Need to be changed
//		15 // ms!!!!!Need to be changed
//};

static void Hus_ButtonChangeState(Hus_ButtonDataStruct * buttonDataStructPoint, uint16_t* pressedPeriodsPoint);

void Hus_ButtonTask( void *pvParameters)
{
	//change the type of the pvParameters
	Hus_ButtonDataStruct * buttonDataStructPoint = (Hus_ButtonDataStruct *)pvParameters;
	uint32_t xLastWakeTime;
	uint16_t pressedPeriods=0;

	//initial some data of the button
	buttonDataStructPoint->hus_button_state = Hus_Button_Detected;
	buttonDataStructPoint->shortPressedFlag = Hus_Flag_Flase;
	buttonDataStructPoint->longPressedFlag = Hus_Flag_Flase;
	buttonDataStructPoint->shortReleasedFlag = Hus_Flag_Flase;
	buttonDataStructPoint->longReleasedFlag = Hus_Flag_Flase;
  //decided the Button is really works. default is True,which means it is working.
  buttonDataStructPoint->buttonOnlineFlag = Hus_Flag_True;


	for( ;; )
    {
      xLastWakeTime = osKernelGetTickCount();
      if(buttonDataStructPoint->buttonOnlineFlag == Hus_Flag_True){
        Hus_ButtonChangeState(buttonDataStructPoint,&pressedPeriods);
      }else{
        if(pressedPeriods != 0){
          pressedPeriods = 0;
        }
      }
      osDelayUntil(xLastWakeTime + pdMS_TO_TICKS(buttonDataStructPoint->DelayTime));//pdMS_TO_TICKS seems not a CMSIS micro;
    }

    /* Tasks must not attempt to return from their implementing
    function or otherwise exit.  In newer FreeRTOS port
    attempting to do so will result in an configASSERT() being
    called if it is defined.  If it is necessary for a task to
    exit then have the task call vTaskDelete( NULL ) to ensure
    its exit is clean. */
	osThreadExit();
 }

void Hus_ButtonChangeState(Hus_ButtonDataStruct * buttonDataStructPoint, uint16_t* pressedPeriodsPoint)
{
	switch(buttonDataStructPoint->hus_button_state)
	{
	case(Hus_Button_Detected):
	{
		if(HAL_GPIO_ReadPin(buttonDataStructPoint->GPIOx,buttonDataStructPoint->GPIO_Pin)==(buttonDataStructPoint->ButtonPressed))
		{
			buttonDataStructPoint->hus_button_state = Hus_Button_Comfirmed;
		}
		break;
	}
	case(Hus_Button_Comfirmed):
	{
		if(HAL_GPIO_ReadPin(buttonDataStructPoint->GPIOx,buttonDataStructPoint->GPIO_Pin)==(buttonDataStructPoint->ButtonPressed))
		{
			buttonDataStructPoint->hus_button_state = Hus_Button_Pressed;
			buttonDataStructPoint->shortPressedFlag = Hus_Flag_True;
			if(buttonDataStructPoint->shortPressedSem!=NULL){
				osSemaphoreRelease(buttonDataStructPoint->shortPressedSem);
			}
		}else
		{
			buttonDataStructPoint->hus_button_state = Hus_Button_Detected;
		}
		break;
	}
	case(Hus_Button_Pressed):
	{
		if(HAL_GPIO_ReadPin(buttonDataStructPoint->GPIOx,buttonDataStructPoint->GPIO_Pin)==(buttonDataStructPoint->ButtonPressed))
		{
			if((*pressedPeriodsPoint) >= (buttonDataStructPoint->LongPressPeriods)){
        //'if' here is to make sure longPressedFlag work only once.
        if(buttonDataStructPoint->longPressedFlag != Hus_Flag_True){
          buttonDataStructPoint->longPressedFlag = Hus_Flag_True;
        }
			}else{
				++(*pressedPeriodsPoint);
			}
		}else
		{
			buttonDataStructPoint->hus_button_state = Hus_Button_Detected;
			if((*pressedPeriodsPoint) >= (buttonDataStructPoint->LongPressPeriods)){
				buttonDataStructPoint->longReleasedFlag = Hus_Flag_True;
				buttonDataStructPoint->shortReleasedFlag = Hus_Flag_True;
			}else{
				buttonDataStructPoint->shortReleasedFlag = Hus_Flag_True;
			}
			*pressedPeriodsPoint = 0;
		}
		break;
	}
	}
}

Hus_State Hus_ButtonIfShortPressed(Hus_ButtonDataStruct* buttonDataStructPoint)
{
	if(buttonDataStructPoint->shortPressedFlag == Hus_Flag_True){
		buttonDataStructPoint->shortPressedFlag = Hus_Flag_Flase;
		return Hus_State_True;
	}else{
		return Hus_State_Flase;
	}
}

Hus_State Hus_ButtonIfLongPressed(Hus_ButtonDataStruct* buttonDataStructPoint)
{
	if(buttonDataStructPoint->longPressedFlag == Hus_Flag_True){
		buttonDataStructPoint->longPressedFlag = Hus_Flag_Flase;
		return Hus_State_True;
	}else{
		return Hus_State_Flase;
	}
}

Hus_State Hus_ButtonIfShortReleased(Hus_ButtonDataStruct* buttonDataStructPoint)
{
	if(buttonDataStructPoint->shortReleasedFlag == Hus_Flag_True){
		buttonDataStructPoint->shortReleasedFlag = Hus_Flag_Flase;
		return Hus_State_True;
	}else{
		return Hus_State_Flase;
	}
}

Hus_State Hus_ButtonIfLongReleased(Hus_ButtonDataStruct* buttonDataStructPoint)
{
	if(buttonDataStructPoint->longReleasedFlag == Hus_Flag_True){
		buttonDataStructPoint->longReleasedFlag = Hus_Flag_Flase;
		return Hus_State_True;
	}else{
		return Hus_State_Flase;
	}
}

void Hus_ButtonOnline(Hus_ButtonDataStruct* buttonDataStructPoint)
{
  buttonDataStructPoint->buttonOnlineFlag = Hus_Flag_True;
}

void Hus_ButtonOffline(Hus_ButtonDataStruct* buttonDataStructPoint)
{
  buttonDataStructPoint->buttonOnlineFlag = Hus_Flag_Flase;
  //initial all of the button changable parameters;
  buttonDataStructPoint->hus_button_state= Hus_Button_Detected;
  buttonDataStructPoint->shortPressedFlag = Hus_Flag_Flase;
  buttonDataStructPoint->shortReleasedFlag = Hus_Flag_Flase;
  buttonDataStructPoint->longPressedFlag = Hus_Flag_Flase;
  buttonDataStructPoint->longReleasedFlag = Hus_Flag_Flase;
}


osStatus_t Hus_ButtonShortPressedAcquire(Hus_ButtonDataStruct* buttonDataStructPoint, uint32_t timeout)
{
	return osSemaphoreAcquire(buttonDataStructPoint->shortPressedSem,timeout);

}

